#include "remotecall.h"
#include <QApplication>
#include <QElapsedTimer>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QThread>
#include <qendian.h>


RemoteCall::RemoteCall() {

}

RemoteCall::~RemoteCall()
{
    proc.kill();
    proc.waitForFinished(3000);
}

bool RemoteCall::releaseFile()
{
    // 释放文件到手机(adb被调用方进程)
    if(!releaseResourceToPath(":/main", QApplication::applicationDirPath(), 1)) return 0;
    QString localPath = QDir(QApplication::applicationDirPath()).filePath("main");
    proc.startDetached("adb", {"push", localPath, remotePath});
    proc.waitForStarted(5000);
    proc.waitForReadyRead(5000);
    QString param1 = "chmod 777 "+remotePath;
    proc.startDetached("adb", {"shell", param1});
    proc.waitForStarted(5000);
    proc.waitForReadyRead(5000);
    return 1;
}

bool RemoteCall::run()
{
    // 启动长期adb shell进程
    // proc.start("adb", {"shell", remotePath}); // 非root
    proc.kill();
    proc.waitForFinished(3000);
    QString param1 = "su -c \""+remotePath+"\"";
    proc.start("adb", {"shell", param1}); // 以root运行
    if (!proc.waitForStarted()) {
        qFatal("无法启动ADB进程");
        return false;
    }
    qDebug() << "进程已启动，状态：" << proc.state();
    return true;
}

bool RemoteCall::isRunning()
{
    return proc.state()!=QProcess::NotRunning;
}

// adb call（检测到\n立即返回）
QByteArray RemoteCall::Call(const QString &data, int timeoutMs) {
    if (!isRunning()) {
        qDebug() << "adb process not running!";
        return QByteArray();
    }

    QElapsedTimer timer;
    timer.start();

    // 发送请求
    QByteArray sendData = data.toUtf8() + '\n';
    proc.write(sendData);

    if (!proc.waitForBytesWritten(20)) {
        qDebug() << "Write timeout";
        return QByteArray();
    }

    QByteArray result;
    bool foundNewline = false;

    while (!timer.hasExpired(timeoutMs)) {
        if (proc.waitForReadyRead(5)) {
            QByteArray chunk = proc.readAll();
            int chunkSize = chunk.size();

            // 检查块的最后一个字符是否为\n
            if (chunkSize > 0 && chunk[chunkSize - 1] == '\n') {
                foundNewline = true;

                // 移除末尾的\n
                if (chunkSize > 1) {
                    // 检查倒数第二个字符是否为\r
                    if (chunk[chunkSize - 2] == '\r') {
                        // 移除\r和\n
                        result.append(chunk.constData(), chunkSize - 2);
                    } else {
                        // 只移除\n
                        result.append(chunk.constData(), chunkSize - 1);
                    }
                }
                break;
            } else {
                // 没有结束符则追加整个块
                result.append(chunk);
            }
        }

        // 更精确的超时检查
        if (timer.hasExpired(timeoutMs)) break;
        QThread::msleep(1);  // 避免CPU忙等待
    }

    return foundNewline ? result : QByteArray();
}

//// 下列是添加的公共成员方法，只是为了方便调用
QString RemoteCall::Call_fun_rect(float width, float height){
    QByteArray res = Call(GJ("fun_rect", {width, height}));
    if(res.isEmpty()) return "";
    return JX(res);
}
///////////////////////////////

QString RemoteCall::GJ(QString fun_name, QJsonArray params){
    QJsonObject req;
    req["function"] = fun_name;
    req["params"] = params;
    return QJsonDocument(req).toJson(QJsonDocument::Compact);
}

QString RemoteCall::JX(QByteArray res_data){
    QJsonObject resObj = QJsonDocument::fromJson(res_data).object();
    if (resObj["error"].isNull()) {
        if(resObj["result"].isString())
            return resObj["result"].toString();
        else if(resObj["result"].isDouble()){
            // 判断数值是否为整数（无小数点）
            double value = resObj["result"].toDouble();
            qlonglong intValue = static_cast<qlonglong>(value);
            if (qFuzzyCompare(value, static_cast<double>(intValue))) {
                // 没有小数点，转换为 long long
                return QString::number(intValue);
            } else {
                // 有小数点，保留 double 格式
                return QString::number(value);
            }
        }else if(resObj["result"].isBool()){
            return QString::number(resObj["result"].toInt());
        }else{
            return "";
        }
    } else {
        // qDebug() << "错误:" << resObj["error"].toString();
    }
    return "";
}
